package com.heima.wemedia.service.impl;


import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.heima.model.common.dtos.PageResponseResult;
import com.heima.model.common.dtos.ResponseResult;
import com.heima.model.common.enums.AppHttpCodeEnum;
import com.heima.model.wemedia.dtos.WmNewsDto;
import com.heima.model.wemedia.dtos.WmNewsPageReqDto;
import com.heima.model.wemedia.pojos.WmMaterial;
import com.heima.model.wemedia.pojos.WmNews;
import com.heima.model.wemedia.pojos.WmNewsMaterial;
import com.heima.utils.common.UserThreadLocalUtil;
import com.heima.wemedia.mapper.WmNewsMapper;
import com.heima.wemedia.service.AutomaticNewsReview;
import com.heima.wemedia.service.IWmMaterialService;
import com.heima.wemedia.service.IWmNewsMaterialService;
import com.heima.wemedia.service.IWmNewsService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.kafka.core.KafkaTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.util.*;
import java.util.stream.Collectors;

/**
 * @author 21236
 */
@Service
public class WmNewsServiceImpl extends ServiceImpl<WmNewsMapper, WmNews> implements IWmNewsService {

    @Autowired
    private IWmMaterialService materialService;

    @Autowired
    private IWmNewsMaterialService newsMaterialService;

    @Autowired
    private AutomaticNewsReview automaticNewsReview;

    @Autowired
    private KafkaTemplate<String, String> kafkaTemplate;

    /**
     * 文章内容列表分页查询
     *
     * @param dto
     * @return
     */
    @Override
    public ResponseResult iPage(WmNewsPageReqDto dto) {

        Date begin = dto.getBeginPubDate();
        Date end = dto.getEndPubDate();

        Page<WmNews> page = page(new Page<WmNews>(dto.getPage(), dto.getSize()), new LambdaQueryWrapper<WmNews>()
                .eq(WmNews::getUserId, UserThreadLocalUtil.getUserId())
                .eq(dto.getStatus() != null, WmNews::getStatus, dto.getStatus())
                .eq(dto.getChannelId() != null, WmNews::getChannelId, dto.getChannelId())
                .like(StringUtils.hasText(dto.getKeyword()), WmNews::getContent, dto.getKeyword())
                .between((begin != null && end != null), WmNews::getPublishTime, begin, end)
                .orderByDesc(WmNews::getCreatedTime));
        PageResponseResult responseResult = new PageResponseResult(dto.getPage(), dto.getSize(), (int) page.getTotal());
        responseResult.setData(page.getRecords());
        return responseResult;
    }

    /**
     * 文章发布
     *
     * @param dto
     * @return
     */
    @Override
    public ResponseResult submit(WmNewsDto dto) {

        WmNews wmnews = saveOrUpdateWmnews(dto);
        if (dto.getStatus() == WmNews.Status.NORMAL.getCode()) {
            return ResponseResult.okResult(true);
        }

        automaticNewsReview.reviewTextAndImages(wmnews);

        //批量新增封面图片素材关联关系
        Integer newsId = wmnews.getId();
        //根据图片url查询素材id
        if (!StringUtils.isEmpty(wmnews.getImages())) {
            List<WmNewsMaterial> wmNewsMaterialList = new ArrayList<>();
            //封面图片素材id
            String wmnewsImages = wmnews.getImages();
            String[] strings = StringUtils.commaDelimitedListToStringArray(wmnewsImages);
            List<String> images = Arrays.asList(strings);
            List<WmMaterial> list = materialService.list(new LambdaQueryWrapper<WmMaterial>().in(WmMaterial::getUrl, images));
            List<Integer> materialIds = list.stream().map(WmMaterial::getId).collect(Collectors.toList());
            for (Integer materialId : materialIds) {
                WmNewsMaterial wmNewsMaterial = new WmNewsMaterial();
                wmNewsMaterial.setType((short) 1);
                wmNewsMaterial.setNewsId(newsId);
                wmNewsMaterial.setMaterialId(materialId);
                wmNewsMaterialList.add(wmNewsMaterial);
            }
            newsMaterialService.saveBatch(wmNewsMaterialList);
        }


        //批量新增素材图片关联关系
        List<String> images = getImages(dto.getContent());
        if (!CollectionUtils.isEmpty(images)) {
            //内容图片素材
            List<WmNewsMaterial> wmNewsMaterialList = new ArrayList<>();
            List<WmMaterial> list = materialService.list(new LambdaQueryWrapper<WmMaterial>().in(WmMaterial::getUrl, images));
            List<Integer> materialIds = list.stream().map(WmMaterial::getId).collect(Collectors.toList());
            for (Integer materialId : materialIds) {
                WmNewsMaterial wmNewsMaterial = new WmNewsMaterial();
                wmNewsMaterial.setType((short) 0);
                wmNewsMaterial.setNewsId(newsId);
                wmNewsMaterial.setMaterialId(materialId);
                wmNewsMaterialList.add(wmNewsMaterial);
            }
            newsMaterialService.saveBatch(wmNewsMaterialList);
        }

        return ResponseResult.okResult(true);
    }

    /**
     * 文章上下架
     *
     * @param dto
     * @return
     */
    @Override
    public ResponseResult downOrUp(WmNewsDto dto) {

        if (dto.getId() == null) {
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID, "文章id不可缺少");
        }

        WmNews news = getById(dto.getId());
        if (news == null) {
            return ResponseResult.errorResult(AppHttpCodeEnum.DATA_NOT_EXIST, "文章不存在");
        }

        if (news.getStatus() != WmNews.Status.PUBLISHED.getCode()) {
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID, "当前文章不是发布状态，不能上下架");
        }

        Short enable = dto.getEnable();
        update(new LambdaUpdateWrapper<WmNews>()
                .eq(WmNews::getId, dto.getId())
                .set(WmNews::getEnable, enable));
        kafkaTemplate.send("article-enable-topic", JSON.toJSONString(news));
        return ResponseResult.errorResult(AppHttpCodeEnum.SUCCESS, "操作成功");
    }

    /**
     * 新增或者更新
     *
     * @param dto
     * @return
     */
    private WmNews saveOrUpdateWmnews(WmNewsDto dto) {
        WmNews wmNews = new WmNews();
        BeanUtils.copyProperties(dto, wmNews);
        //补充字段
        Date now = new Date();
        wmNews.setUserId(UserThreadLocalUtil.getUserId());
        wmNews.setCreatedTime(now);
        wmNews.setSubmitedTime(now);
        if (null != dto.getId()) {
            //更新，删除关联关系
            newsMaterialService.remove(new LambdaQueryWrapper<WmNewsMaterial>().eq(WmNewsMaterial::getNewsId, dto.getId()));
            wmNews = contentProcessing(wmNews, dto);
            updateById(wmNews);

        } else {
            //新增
            wmNews = contentProcessing(wmNews, dto);
            save(wmNews);

        }
        return wmNews;
    }

    /**
     * 设置type，images
     *
     * @param wmNews
     * @param dto
     * @return
     */
    private WmNews contentProcessing(WmNews wmNews, WmNewsDto dto) {
        if (dto.getType() == -1) {
            String content = dto.getContent();
            List<String> images = getImages(content);
            int size = images.size();
            if (size >= 3) {
                wmNews.setType((short) 3);
                List<String> collect = images.stream().limit(3).collect(Collectors.toList());
                wmNews.setImages(StringUtils.collectionToCommaDelimitedString(collect));
            } else if (size >= 1) {
                wmNews.setType((short) 1);
                List<String> collect = images.stream().limit(1).collect(Collectors.toList());
                wmNews.setImages(StringUtils.collectionToCommaDelimitedString(collect));
            } else {
                wmNews.setType((short) 0);
            }
        } else {
            List<String> images = dto.getImages();
            if (!CollectionUtils.isEmpty(images)) {
                wmNews.setImages(StringUtils.collectionToCommaDelimitedString(images));
            }
        }
        return wmNews;
    }

    /**
     * 获取文章内容的图片
     *
     * @param content
     * @return
     */
    private static List<String> getImages(String content) {
        List<String> images = new ArrayList<>();
        List<Map> mapList = JSONArray.parseArray(content, Map.class);
        for (Map map : mapList) {
            String type = (String) map.get("type");
            if ("image".equals(type)) {
                String value = (String) map.get("value");
                images.add(value);
            }
        }
        return images;
    }

}
